home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Reference Guide
/
C-C++ Interactive Reference Guide.iso
/
c_ref
/
csource5
/
311_01
/
db_var.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-23
|
11KB
|
456 lines
/****************************************************************************/
/* */
/* */
/* db_var.c v1.3 (c) 1990 Ken Harris */
/* */
/* */
/****************************************************************************/
/* */
/* This software is made available on an AS-IS basis. Unrestricted */
/* use is granted provided that the copyright notice remains intact. */
/* The author makes no warranties expressed or implied. */
/* */
/****************************************************************************/
#include "dblib.h"
#ifdef ANSI
void db_var_bld_csum(BUFFER);
void db_var_chk_csum(BUFFER);
#else
void db_var_bld_csum();
void db_var_chk_csum();
#endif
/*
* db_add_var - Add a record to a variable file
*/
void db_add_var(df, user_data, data_size)
DATA_FILE df;
char *user_data;
int data_size;
{
FILE_HDR fh;
BUFFER buf;
VAR_REC vbuf;
db_error = 0;
fh = (FILE_HDR) df->df_fhdr->buf_data;
buf = df->df_buf;
buf->buf_cur_blk = fh->fh_vfile_size;
buf->buf_rec_inx = 0;
buf->buf_cur_size = sizeof(struct db_var_rec) + data_size;
if (data_size < 1 || buf->buf_cur_size > buf->buf_size)
{ db_error = DB_VAR_SIZE_ERROR;
return;
}
db_add_blk = buf->buf_cur_blk;
db_add_rec = buf->buf_rec_inx;
vbuf = (VAR_REC) buf->buf_data;
vbuf->var_stat = DB_INUSE;
vbuf->var_dsize = data_size;
memcpy(vbuf->var_data, user_data, data_size);
db_var_bld_csum(buf);
fh->fh_rec_cnt++;
fh->fh_vfile_size += buf->buf_cur_size;
db_put_blk(df,df->df_fhdr);
db_put_blk(df,buf);
}
/*
* db_read_first_var - Read First Record in a Variable File
*/
void db_read_first_var(df, user_data, data_size)
DATA_FILE df;
char *user_data;
int *data_size;
{
FILE_HDR fh;
BUFFER buf;
VAR_REC vrec;
ulong psn;
db_error = 0;
fh = (FILE_HDR) df->df_fhdr->buf_data;
buf = df->df_buf;
vrec = (VAR_REC) buf->buf_data;
for (psn=DB_FILE_HDR_SIZE; psn < fh->fh_vfile_size;)
{ db_get_blk(df, psn, buf);
if (db_error) return;
db_var_chk_csum(buf);
if (db_error) return;
buf->buf_cur_size = sizeof(struct db_var_rec)
+ vrec->var_dsize;
if (vrec->var_stat == DB_INUSE)
{ *data_size = vrec->var_dsize;
memcpy(user_data, vrec->var_data, *data_size);
return;
}
psn += buf->buf_cur_size;
}
db_error= DB_END_OF_FILE;
}
/*
* db_read_next_var - Read Next Record in a Variable File
*/
void db_read_next_var(df, user_data, data_size)
DATA_FILE df;
char *user_data;
int *data_size;
{
FILE_HDR fh;
BUFFER buf;
VAR_REC vrec;
ulong psn;
db_error = 0;
fh = (FILE_HDR) df->df_fhdr->buf_data;
buf = df->df_buf;
vrec = (VAR_REC) buf->buf_data;
psn = df->df_prev_blk + df->df_prev_vsize;
while (psn < fh->fh_vfile_size)
{ db_get_blk(df, psn, buf);
if (db_error) return;
db_var_chk_csum(buf);
if (db_error) return;
buf->buf_cur_size = sizeof(struct db_var_rec)
+ vrec->var_dsize;
if (vrec->var_stat == DB_INUSE)
{ *data_size = vrec->var_dsize;
memcpy(user_data, vrec->var_data, *data_size);
return;
}
psn += buf->buf_cur_size;
}
db_error= DB_END_OF_FILE;
}
/*
* db_read_last_var - Read Last Record in a Variable File
*/
void db_read_last_var(df, user_data, data_size)
DATA_FILE df;
char *user_data;
int *data_size;
{
FILE_HDR fh;
BUFFER buf;
VAR_REC vrec;
ulong psn;
char *c, *d;
short vsize;
db_error = 0;
fh = (FILE_HDR) df->df_fhdr->buf_data;
buf = df->df_buf;
for (psn=fh->fh_vfile_size; psn >= DB_FILE_HDR_SIZE;)
{ psn -= buf->buf_size;
db_get_blk(df, psn, buf);
if (db_error) return;
psn = buf->buf_cur_blk;
c = buf->buf_data + buf->buf_cur_size - 2;
d = (char *)&vsize;
*d++ = *c++;
*d = *c;
buf->buf_rec_inx = buf->buf_size
- sizeof(struct db_var_rec) - vsize;
buf->buf_cur_size = sizeof(struct db_var_rec) + vsize;
db_var_chk_csum(buf);
if (db_error) return;
vrec = (VAR_REC)(buf->buf_data + buf->buf_rec_inx);
if (vrec->var_stat == DB_INUSE)
{ *data_size = vrec->var_dsize;
memcpy(user_data, vrec->var_data, *data_size);
return;
}
}
db_error= DB_END_OF_FILE;
}
/*
* db_read_prev_var - Read Previous Record in a Variable File
*/
void db_read_prev_var(df, user_data, data_size)
DATA_FILE df;
char *user_data;
int *data_size;
{
FILE_HDR fh;
BUFFER buf;
VAR_REC vrec;
ulong psn;
char *c, *d;
short vsize;
db_error = 0;
fh = (FILE_HDR) df->df_fhdr->buf_data;
buf = df->df_buf;
for (psn=df->df_prev_blk+df->df_prev_rec; psn >= DB_FILE_HDR_SIZE;)
{ psn -= buf->buf_size;
db_get_blk(df, psn, buf);
if (db_error) return;
psn = buf->buf_cur_blk;
c = buf->buf_data + buf->buf_cur_size - 2;
d = (char *)&vsize;
*d++ = *c++;
*d = *c;
buf->buf_rec_inx = buf->buf_cur_size
- sizeof(struct db_var_rec) - vsize;
buf->buf_cur_size = sizeof(struct db_var_rec) + vsize;
db_var_chk_csum(buf);
if (db_error) return;
vrec = (VAR_REC)(buf->buf_data + buf->buf_rec_inx);
if (vrec->var_stat == DB_INUSE)
{ *data_size = vrec->var_dsize;
memcpy(user_data, vrec->var_data, *data_size);
return;
}
}
db_error= DB_END_OF_FILE;
}
/*
* db_update_var - Update Record in a Variable File
*/
void db_update_var(df, user_data)
DATA_FILE df;
char *user_data;
{
FILE_HDR fh;
BUFFER buf;
VAR_REC vrec;
db_error = 0;
fh = (FILE_HDR) df->df_fhdr->buf_data;
buf = df->df_buf;
if (buf->buf_cur_blk == 0)
{ db_error = DB_NO_CURRENT_REC;
return;
}
vrec = (VAR_REC)(buf->buf_data + buf->buf_rec_inx);
if (vrec->var_stat != DB_INUSE)
{ db_error = DB_DELETED_REC;
return;
}
memcpy(vrec->var_data, user_data, vrec->var_dsize);
db_var_bld_csum(buf);
db_put_blk(df, buf);
}
/*
* db_delete_var - Delete Record in a Variable File
*/
void db_delete_var(df)
DATA_FILE df;
{
FILE_HDR fh;
BUFFER buf;
VAR_REC vrec;
char *c;
int i;
db_error = 0;
fh = (FILE_HDR) df->df_fhdr->buf_data;
buf = df->df_buf;
if (buf->buf_cur_blk == 0)
{ db_error = DB_NO_CURRENT_REC;
return;
}
vrec = (VAR_REC)(buf->buf_data + buf->buf_rec_inx);
if (vrec->var_stat != DB_INUSE)
{ db_error = DB_DELETED_REC;
return;
}
vrec->var_stat = DB_FREE;
for (i=0, c=vrec->var_data; i < vrec->var_dsize; i++) *c++ = 0;
fh->fh_rec_cnt--;
db_var_bld_csum(buf);
db_put_blk(df, buf);
db_put_blk(df,buf);
}
/*
* db_reorg_var - Reorganize a Variable File
*/
void db_reorg_var(new_df)
DATA_FILE new_df;
{
DATA_FILE old_df;
FILE_HDR old_fh, new_fh;
char *vrec, *calloc();
int vsize;
db_error = 0;
old_df = (DATA_FILE) calloc(1, sizeof(struct db_data_file));
if (!old_df)
{ db_error = DB_ALLOC_ERROR;
return;
}
old_df->df_fhdr = db_alloc_buf(DB_FILE_HDR_SIZE);
old_fh = (FILE_HDR) old_df->df_fhdr->buf_data;
if (db_error) { db_free_df(old_df); return; }
new_fh = (FILE_HDR) new_df->df_fhdr->buf_data;
memcpy(old_fh, new_fh, sizeof(struct db_file_hdr));
new_fh->fh_rec_cnt = 0;
new_fh->fh_vfile_size = DB_FILE_HDR_SIZE;
old_df->df_stat = DB_OPEN;
old_df->df_fd = new_df->df_fd;
old_df->df_buf = db_alloc_buf(old_fh->fh_block_size);
if (db_error) { db_free_df(old_df); return; }
vrec = calloc(1, old_fh->fh_data_size);
if (!vrec)
{ db_error = DB_ALLOC_ERROR;
return;
}
db_read_first(old_df, vrec, &vsize);
while (!db_error)
{ db_add(new_df, vrec, vsize);
if (db_error) break;
db_read_next(old_df, vrec, &vsize);
}
if (db_error == DB_END_OF_FILE) db_error = 0;
free(vrec);
db_free_df(old_df);
}
/*
* db_var_bld_csum - Compute var record check sum
*/
void db_var_bld_csum(buf)
BUFFER buf;
{
VAR_REC var;
int cnt;
char *c, *d, csum;
if (buf->buf_cur_blk == 0) return;
var = (VAR_REC) (buf->buf_data + buf->buf_rec_inx);
for (cnt=0, csum=0, c = var->var_data; cnt < var->var_dsize; cnt++)
csum ^= *c++;
*c = csum;
c = ((char *)var) + sizeof(struct db_var_rec) + var->var_dsize - 2;
d = (char *)&var->var_dsize;
*c++ = *d++;
*c = *d;
}
/*
* db_var_chk_csum - Check var record check sum
*/
void db_var_chk_csum(buf)
BUFFER buf;
{
VAR_REC var;
short cnt;
char *c, *d, csum;
db_error = 0;
if (buf->buf_cur_blk == 0) return;
var = (VAR_REC) (buf->buf_data + buf->buf_rec_inx);
if (var->var_dsize <= 0 ||
var->var_dsize > buf->buf_cur_size - sizeof(struct db_var_rec))
{ db_error = DB_VAR_CSUM_ERROR;
return;
}
for (cnt=0, csum=0, c = var->var_data; cnt < var->var_dsize; cnt++)
csum ^= *c++;
if (*c != csum)
{ db_error = DB_VAR_CSUM_ERROR;
return;
}
c = ((char *)var) + sizeof(struct db_var_rec) + var->var_dsize - 2;
d = (char *)&cnt;
*d++ = *c++;
*d = *c;
if (cnt != var->var_dsize)
{ db_error = DB_VAR_SIZE_ERROR;
return;
}
}